/*
 * RouteSelectionPanel.java
 * 
 * Copyright 2008 David D. Emory
 * 
 * This file is part of Five Points. See <http://www.fpdev.org> for
 * additional information regarding the project.
 * 
 * Five Points is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Five Points is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Five Points.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.fpdev.apps.admin.gui;

import org.fpdev.apps.admin.gui.dialogs.RoutePropertiesDialog;
import org.fpdev.util.gui.GUIFactory;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import org.fpdev.core.transit.Route;
import org.fpdev.core.transit.SubRoute;
import org.fpdev.apps.admin.AdminClient;
import java.awt.event.*;
import java.util.Iterator;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
import org.fpdev.core.transit.Provider;
import org.fpdev.apps.admin.ACEvent;
import org.fpdev.apps.admin.EventTypes;
import org.fpdev.core.transit.CalendarService;
import org.fpdev.util.FPUtil;
import org.fpdev.util.gui.UneditableTableModel;

public class RouteSelectionPanel extends JPanel
        implements ActionListener {

  private AdminClient av_;
  private SubRoutePropertiesFrame subPropsFrame_;
  private JCheckBox showInherited_;
  private JComboBox providersCBox_;
  private JButton newProvBtn_,  delProvBtn_,  editProvBtn_;
  private JButton newRteBtn_,  delRteBtn_,  rtePropBtn_;
  private JButton newSubBtn_;//, subAutoBtn_, subPropBtn_, delSubBtn_, zoomSubBtn_;
  // Context Menus:
  private JPopupMenu newSubMenu_,  rteRightClickMenu_,  subRightClickMenu_;
  // Right-click Route Context Menu Items:
  private JMenuItem routePropsMI_,  deleteRouteMI_;
  // "New Subroute" Button Context Menu Items:
  private JMenuItem newSubMI_,  nbsbMI_,  nbsbSufMI_,  ebwbMI_,  ebwbSufMI_;
  // Right-click Subroute Context Menu Items:
  private JMenuItem zoomSubAllMI_,  zoomSubEndMI_,  zoomSubStartMI_,  subPropsMI_,  deleteSubMI_, copySubOtherMI_;
  private JMenu copySubMenu_, copySubInternal_;
  private JTable routesTable_,  subsTable_;
  private ListSelectionModel subsLSM_;
  private Provider[] providerLookup_;
  private Route[] routeLookup_;
  private boolean handleSubSelection_;

  public RouteSelectionPanel(AdminClient cv) {
    //setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
    setBorder(new CompoundBorder(new TitledBorder("Transit Routes"), new EmptyBorder(2, 4, 2, 4)));//new EmptyBorder(8,8,8,8));

    av_ = cv;

    int btnWidth = 45;
    handleSubSelection_ = true;

    showInherited_ = GUIFactory.newCheckBox("Show Inherited Routes");
    showInherited_.addActionListener(this);

    providersCBox_ = GUIFactory.newComboBox(150);

    providersCBox_.addItemListener(new ItemListener() {

      @Override
      public void itemStateChanged(ItemEvent e) {
        if (e.getStateChange() == ItemEvent.SELECTED) {
          updateRoutes();
        }
      }
    });

    newProvBtn_ = GUIFactory.newButton("New", btnWidth, this);


    routesTable_ = new JTable();
    routesTable_.setMinimumSize(new Dimension(40, 80));
    routesTable_.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

    // Route right-click context menu
    rteRightClickMenu_ = new JPopupMenu();
    routePropsMI_ = newPopupMenuItem(rteRightClickMenu_, "Route Properties");
    deleteRouteMI_ = newPopupMenuItem(rteRightClickMenu_, "Delete Route");

    routesTable_.addMouseListener(new MouseAdapter() {

      @Override
      public void mouseClicked(MouseEvent e) {
        if (e.getClickCount() >= 2) {
          int row = routesTable_.rowAtPoint(e.getPoint());
          av_.msg("d-click rte " + row);
        }
      }

      @Override
      public void mousePressed(MouseEvent e) {
        if (e.getButton() == MouseEvent.BUTTON3) {
          int row = routesTable_.rowAtPoint(e.getPoint());
          routesTable_.changeSelection(row, 0, false, false);
          rteRightClickMenu_.show(routesTable_, e.getX(), e.getY());
        }
      }
    });
    ListSelectionModel rteLSM = routesTable_.getSelectionModel();
    rteLSM.addListSelectionListener(new ListSelectionListener() {

      @Override
      public void valueChanged(ListSelectionEvent e) {
        if (e.getValueIsAdjusting()) {
          return;
        } //Ignore extra messages.
        if (!((ListSelectionModel) e.getSource()).isSelectionEmpty()) { // && handleSubSelection_) {
          routeSelected();
        }
      }
    });


    subsTable_ = new JTable();
    subsTable_.setMinimumSize(new Dimension(40, 40));
    subsTable_.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

    // Subroute right-click context menu
    subRightClickMenu_ = new JPopupMenu();
    zoomSubAllMI_ = newPopupMenuItem(subRightClickMenu_, "Zoom to Full Path");
    zoomSubStartMI_ = newPopupMenuItem(subRightClickMenu_, "Zoom to Start of Path");
    zoomSubEndMI_ = newPopupMenuItem(subRightClickMenu_, "Zoom to End of Path");
    subPropsMI_ = newPopupMenuItem(subRightClickMenu_, "Subroute Properties");
    deleteSubMI_ = newPopupMenuItem(subRightClickMenu_, "Delete Subroute");
    copySubMenu_ = new JMenu("Copy Subroute From..");
    copySubMenu_.addMouseListener(new MouseAdapter() {
      @Override
      public void mouseEntered(MouseEvent evt) {
        System.out.println("mouse entered");
        populateCopySubInternalMenu();
      }
    });
    copySubOtherMI_ = new JMenuItem("Other Route");
    copySubOtherMI_.addActionListener(this);
    copySubInternal_ = new JMenu("This Route");
    copySubMenu_.add(copySubInternal_);
    copySubMenu_.add(copySubOtherMI_);
    subRightClickMenu_.add(copySubMenu_);

    subsTable_.addMouseListener(new MouseAdapter() {

      @Override
      public void mouseClicked(MouseEvent e) {
        if (e.getClickCount() >= 2) {
          //int row = subsTable_.rowAtPoint(e.getPoint());
          RouteSelectionPanel.this.showSubRouteProperties();
        }
      }

      @Override
      public void mousePressed(MouseEvent e) {
        if (e.getButton() == MouseEvent.BUTTON3) {
          int row = subsTable_.rowAtPoint(e.getPoint());
          subsTable_.changeSelection(row, 0, false, false);
          subRightClickMenu_.show(subsTable_, e.getX(), e.getY());
        }
      }
    });
    ListSelectionModel subLSM = subsTable_.getSelectionModel();
    subLSM.addListSelectionListener(new ListSelectionListener() {

      @Override
      public void valueChanged(ListSelectionEvent e) {

        if (e.getValueIsAdjusting()) {
          return;
        } //Ignore extra messages.
        subsLSM_ = (ListSelectionModel) e.getSource();
        if (!subsLSM_.isSelectionEmpty() && handleSubSelection_) {
          subSelected();
        //int selectedRow = subsLSM_.getMinSelectionIndex();
        //subsTableRowSelected(selectedRow);
        }
      }
    });


    newRteBtn_ = GUIFactory.newButton("New", btnWidth, this);
    rtePropBtn_ = GUIFactory.newButton("Info", btnWidth, this);
    delRteBtn_ = GUIFactory.newButton("Delete", btnWidth, this);

    JPanel rteBtnCol = new JPanel();
    rteBtnCol.setLayout(new BoxLayout(rteBtnCol, BoxLayout.Y_AXIS));
    rteBtnCol.add(newRteBtn_);
    rteBtnCol.add(rtePropBtn_);
    rteBtnCol.add(delRteBtn_);

    newSubBtn_ = GUIFactory.newButton("New...", btnWidth, this);

    newSubMenu_ = new JPopupMenu();

    newSubMI_ = this.newPopupMenuItem(newSubMenu_, "Single Subroute");
    nbsbMI_ = this.newPopupMenuItem(newSubMenu_, "Auto-create: NB & SB");
    nbsbSufMI_ = this.newPopupMenuItem(newSubMenu_, "Auto-create: NB_{X} & SB_{X}");
    ebwbMI_ = this.newPopupMenuItem(newSubMenu_, "Auto-create: EB & WB");
    ebwbSufMI_ = this.newPopupMenuItem(newSubMenu_, "Auto-create: EB_{X} & WB_{X}");

    newSubBtn_.addMouseListener(new MouseAdapter() {

      @Override
      public void mousePressed(MouseEvent e) {
        newSubMenu_.show(newSubBtn_, e.getX(), e.getY());
      }
    });

    // create & add providers row
    JPanel provsPanel = new JPanel();
    provsPanel.setLayout(new BoxLayout(provsPanel, BoxLayout.Y_AXIS));

    provsPanel.add(new JLabel("All Providers:"));
    JPanel provRow = new JPanel(new BorderLayout());
    provRow.add(providersCBox_, BorderLayout.CENTER);
    provRow.add(newProvBtn_, BorderLayout.EAST);
    provRow.setAlignmentX(LEFT_ALIGNMENT);
    provsPanel.add(provRow);

    //rtesPanel.add(Box.createVerticalStrut(6));

    // create & add routes panel
    JPanel rtesPanel = new JPanel(new BorderLayout());
    //rtesPanel.setLayout(new BoxLayout(rtesPanel, BoxLayout.Y_AXIS));

    JPanel rtesHeaderPanel = new JPanel(new BorderLayout());
    rtesHeaderPanel.add(new JLabel("Member Routes:"), BorderLayout.WEST);
    rtesHeaderPanel.add(newRteBtn_, BorderLayout.EAST);

    rtesPanel.add(rtesHeaderPanel, BorderLayout.NORTH);
    rtesPanel.add(new JScrollPane(routesTable_), BorderLayout.CENTER);
    rtesPanel.add(Box.createVerticalStrut(80), BorderLayout.EAST);
    rtesPanel.setAlignmentX(LEFT_ALIGNMENT);
    rtesPanel.setPreferredSize(new Dimension(300, 120));

    JPanel subsHeaderPanel = new JPanel(new BorderLayout());
    subsHeaderPanel.add(new JLabel("Member Subroutes:"), BorderLayout.WEST);
    subsHeaderPanel.add(newSubBtn_, BorderLayout.EAST);

    // create & add subroutes panel
    JPanel subPanel = new JPanel(new BorderLayout());
    subPanel.add(subsHeaderPanel, BorderLayout.NORTH);
    subPanel.add(new JScrollPane(subsTable_), BorderLayout.CENTER);
    subPanel.add(Box.createVerticalStrut(80), BorderLayout.EAST);
    subPanel.setAlignmentX(LEFT_ALIGNMENT);
    subPanel.setPreferredSize(new Dimension(300, 120));

    JPanel routesSubsPanel = new JPanel();
    routesSubsPanel.setLayout(new BoxLayout(routesSubsPanel, BoxLayout.Y_AXIS));
    routesSubsPanel.add(Box.createVerticalStrut(10));
    routesSubsPanel.add(rtesPanel);
    routesSubsPanel.add(Box.createVerticalStrut(5));
    routesSubsPanel.add(showInherited_);
    routesSubsPanel.add(Box.createVerticalStrut(10));
    routesSubsPanel.add(subPanel);

    setLayout(new BorderLayout());
    add(provsPanel, BorderLayout.NORTH);
    add(routesSubsPanel, BorderLayout.CENTER);

    routeDeselected();

    subPropsFrame_ = new SubRoutePropertiesFrame(av_);
  }

  private JMenuItem newPopupMenuItem(JPopupMenu menu, String text) {
    JMenuItem item = new JMenuItem(text);
    item.addActionListener(this);
    menu.add(item);
    return item;
  }

  private void populateCopySubInternalMenu() {
    Route rte = getSelectedRoute();
    copySubInternal_.removeAll();

    for(final SubRoute sub : rte.getSubRoutes()) {
      if(sub == getSelectedSubRoute()) continue;
      
      JMenuItem item = new JMenuItem(sub.getID());
      copySubInternal_.add(item);
      item.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          av_.getRouteOps().importRoutePath(sub, false);
        }
      });

      JMenuItem revItem = new JMenuItem(sub.getID()+" (reversed)");
      copySubInternal_.add(revItem);
      revItem.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          av_.getRouteOps().importRoutePath(sub, true);
        }
      });

    }
  }

  @Override
  public void actionPerformed(ActionEvent e) {

    if (e.getSource() == showInherited_) {
      updateRoutes();
    }

    if (e.getSource() == newProvBtn_) {
      av_.fireEvent(new ACEvent(EventTypes.RTEPANEL_NEW_PROVIDER));
    }

    if (e.getSource() == newRteBtn_) {
      av_.fireEvent(new ACEvent(EventTypes.RTEPANEL_NEW_ROUTE));
    }

    // Route Right-Click Menu Actions
    if (e.getSource() == routePropsMI_) {
      new RoutePropertiesDialog(av_, getSelectedRoute());
      int selItem = routesTable_.getSelectedRow();
      updateRoutes(false);
      routesTable_.getSelectionModel().setSelectionInterval(selItem, selItem);
    }
    if (e.getSource() == deleteRouteMI_) {
      String query = "Are you sure you want to delete the route \"" + getSelectedRoute().getID() + " - " + getSelectedRoute().getName() + "\"?";
      if (routesTable_.getSelectedRow() != -1 &&
              JOptionPane.showConfirmDialog(av_.getGUI(), query, "Confirm Delete", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {

        av_.getRouteOps().deleteRoute(getSelectedRoute().getCombinedID());
        routeDeselected();
        subDeselected();
      }
    }


    // New Subroute Menu Actions
    if (e.getSource() == newSubMI_) {
      int index = av_.getRouteOps().newSubRoute();
      updateSubs();
      subsTable_.getSelectionModel().setSelectionInterval(index, index);
    }
    String[] nbsb = {"NB", "SB"};
    String[] ebwb = {"EB", "WB"};
    if (e.getSource() == nbsbMI_) {
      av_.getRouteOps().autoAddSubRoutes(nbsb, "");
    }
    if (e.getSource() == nbsbSufMI_) {
      av_.getRouteOps().autoAddSubRoutes(nbsb, JOptionPane.showInputDialog("Suffix:"));
    }
    if (e.getSource() == ebwbMI_) {
      av_.getRouteOps().autoAddSubRoutes(ebwb, "");
    }
    if (e.getSource() == ebwbSufMI_) {
      av_.getRouteOps().autoAddSubRoutes(ebwb, JOptionPane.showInputDialog("Suffix:"));
    }

    // Subroute Right-Click Menu Actions
    if ((e.getSource() == zoomSubAllMI_ || e.getSource() == zoomSubStartMI_ || e.getSource() == zoomSubEndMI_) &&
            av_.getRouteOps().getActiveSubRoute().getPath().linkCount() == 0) {
      av_.msg("No path assigned to subroute");
    } else {
      // various zoom-to-path options:
      if (e.getSource() == zoomSubAllMI_) {
        av_.getGUI().getMapPanel().zoomPath(av_.getRouteOps().getActiveSubRoute().getPath());
      }
      if (e.getSource() == zoomSubStartMI_) {
        av_.getGUI().getMapPanel().recenter(av_.getRouteOps().getActiveSubRoute().getPath().startNode());
      }
      if (e.getSource() == zoomSubEndMI_) {
        av_.getGUI().getMapPanel().recenter(av_.getRouteOps().getActiveSubRoute().getPath().endNode());
      }
    }
    if (e.getSource() == subPropsMI_) {
      showSubRouteProperties();
    }
    if (e.getSource() == deleteSubMI_) {
      String subID = (String) subsTable_.getValueAt(subsLSM_.getMinSelectionIndex(), 0);
      String query = "Are you sure you want to delete the subroute \"" + getSelectedRoute().getSubRoute(subID).getFullID() + "\"?";
      if (subsLSM_.getMinSelectionIndex() != -1 &&
              JOptionPane.showConfirmDialog(av_.getGUI(), query, "Confirm Delete", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
        //getSelectedRoute().deleteSubRoute(subID, av_.getEngine().getRouteNetwork());
        subDeselected();
        av_.getRouteOps().deleteSubRoute(subID);

      //updateSubs();
      }
    }
    if (e.getSource() == copySubOtherMI_) {
      av_.fireEvent(new ACEvent(EventTypes.RTEMENU_IMPORT_PATH_INTERNAL));
    }
  }

  ////////////////////////// PROVIDER-RELATED METHODS //////////////////////////

  public Provider getSelectedProvider() {
    if(providersCBox_.getSelectedIndex() == -1) return null;
    return providerLookup_[providersCBox_.getSelectedIndex()];
  }

  public void updateProviders() {
    providersCBox_.removeAllItems();
    providerLookup_ = new Provider[av_.getEngine().getRoutes().getProviders().providerCount()];
    int i = 0;
    Iterator<Provider> provIter = av_.getEngine().getRoutes().getProviders().getIteratorSortedBySize(av_.getEngine().getRoutes());
    while (provIter.hasNext()) {
      Provider p = provIter.next();
      providerLookup_[i] = p;
      providersCBox_.addItem(p.getName());
      i++;
    }

  }

  public void selectProvider(Provider p) {
    int i;
    for(i=0; i<providerLookup_.length; i++) {
      if(providerLookup_[i] == p) break;
    }
    providersCBox_.setSelectedIndex(i);
  }

  
  /////////////////////////// ROUTE-RELATED METHODS ////////////////////////////

  public void updateRoutes() {
    updateRoutes(true);
  }

  public void updateRoutes(boolean updateSubs) {

    int count = 0;
    if(getSelectedProvider() != null)
      count = av_.getRouteOps().getRoutes().routeCount(getSelectedProvider(), av_.getActiveScenario(), showInherited_.isSelected());

    System.out.println("count = " + count);
    routeLookup_ = new Route[count];

    //int selectedRow = subsLSM_ != null ? subsLSM_.getMinSelectionIndex(): -1;

    String[] colNames = new String[3];
    colNames[0] = "ID";
    colNames[1] = "Name";
    colNames[2] = "Subs";

    String[][] table = new String[count][3];

    if (count > 0) {

      Iterator<Route> routes = av_.getEngine().getRoutes().getCollectionSortedByID(av_.getActiveScenario(), showInherited_.isSelected(), getSelectedProvider()).iterator();

      for (int r = 0; r < count; r++) {
        Route route = routes.next();

        routeLookup_[r] = route;

        table[r][0] = route.getID();
        table[r][1] = route.getName();
        table[r][2] = route.subRouteCount() > 0 ? route.subRouteCount() + " (" + route.subRouteWithTimetablesCount() + ")" : "[none]";
      }
    }
    UneditableTableModel model = new UneditableTableModel(table, colNames);


    routesTable_.setModel(model);
    routesTable_.doLayout();
    FPUtil.setPreferredColumnWidths(routesTable_, new double[]{0.2, 0.6, 0.2});

    this.revalidate();

    if (updateSubs) {
      updateSubs();
    }

  }

  public void routeSelected() {
    subDeselected();
    if (routesTable_.getSelectedRow() != -1) {
      updateSubs();
    }
    newSubBtn_.setEnabled(true);
  }

  public void routeDeselected() {
    newSubBtn_.setEnabled(false);
  }

  public Route getSelectedRoute() {
    return routeLookup_[routesTable_.getSelectedRow()];
  }

  public int getSelectedRouteIndex() {
    return routesTable_.getSelectedRow();
  }

  public void selectRouteByID(String id) {
    int found = -1;
    for (int row = 0; row < routesTable_.getRowCount(); row++) {
      if (routesTable_.getModel().getValueAt(row, 0).equals(id)) {
        found = row;
        break;
      }
    }
    if (found >= 0) {
      routesTable_.getSelectionModel().setSelectionInterval(found, found);
      routesTable_.scrollRectToVisible(routesTable_.getCellRect(found, 0, true));
    }
  }

  public void selectRouteByIndex(int index) {
    routesTable_.getSelectionModel().setSelectionInterval(index, index);
  }


  public static String getRouteDisplayStr(Route route) {
    return route.getID() + " - " + (route.getName().length() > 0 ? route.getName() : "(unnamed)");
  }

  ////////////////////////// SUBROUTE-RELATED METHODS //////////////////////////

  public void subsTableRowSelected(int row) {
    av_.msg("subsTable row " + row);
  }

  public void updateSubs() {
    int subCount = routesTable_.getSelectedRow() >= 0 ? getSelectedRoute().subRouteCount() : 0;

    int selectedRow = subsLSM_ != null ? subsLSM_.getMinSelectionIndex() : -1;

    String[] colNames = new String[4];
    colNames[0] = "ID";
    colNames[1] = "Mode";
    colNames[2] = "Path";
    colNames[3] = "Days";

    String[][] table = new String[subCount][4];

    if (subCount > 0) {

      Iterator<SubRoute> subs = getSelectedRoute().getSubRoutes().iterator();

      for (int r = 0; r < subCount; r++) {
        SubRoute sub = subs.next();
        table[r][0] = sub.getID();
        table[r][1] = sub.getPath().getType().getName();
        table[r][2] = sub.linkCount() == 0 ? "(none)" : sub.linkCount() + " link" + (sub.linkCount() > 1 ? "s" : "");
        String days = "";

        for(CalendarService service : av_.getEngine().getRoutes().getCalendarServices().getServices()) {
          days += sub.hasTable(service) ?
            (sub.getTable(service).isFileSaved() ? service.getID()+"," : service.getID()+"*,") : "";
        }
        /*days += sub.hasTable(Timetable.DayOfWeek.WEEKDAY) ?
          (sub.getTable(Timetable.DayOfWeek.WEEKDAY).isFileSaved() ? "Wk," : "Wk*,") : "";
        days += sub.hasTable(Timetable.DayOfWeek.SATURDAY) ?
          (sub.getTable(Timetable.DayOfWeek.SATURDAY).isFileSaved() ? "Sa," : "Sa*,") : "";
        days += sub.hasTable(Timetable.DayOfWeek.SUNDAY) ?
          (sub.getTable(Timetable.DayOfWeek.SUNDAY).isFileSaved() ? "Su," : "Su*,") : "";*/

        table[r][3] = days.length() > 0 ? days.substring(0, days.length() - 1) : "(none)";
      }
    }
    UneditableTableModel model = new UneditableTableModel(table, colNames);
    subsTable_.setModel(model);
    subsTable_.doLayout();
    if (selectedRow >= 0) {
      handleSubSelection_ = false;
      subsLSM_.setSelectionInterval(selectedRow, selectedRow);
      handleSubSelection_ = true;
    }

    this.revalidate();

  }

  public void subSelected() {
    SubRoute sub = getSelectedSubRoute();

    if(!sub.initialized()) {
      av_.getEngine().initLinks(sub.getLinkIDs());
      sub.initPath(av_.getEngine().getBaseNet());
    }

    av_.getRouteOps().setActiveSubRoute(sub);
    av_.getGUI().getTPathOptionsPanel().setSelectedType(sub.getPath().getType());
    subPropsFrame_.setSubRoute(sub);
  }

  public void subDeselected() {
    subsLSM_ = null;
    av_.getRouteOps().setActiveSubRoute(null);
    av_.getGUI().getMapPanel().refresh(false, false, true);
  }

  public SubRoute getSelectedSubRoute() {
    return getSelectedRoute().getSubRoute((String) subsTable_.getValueAt(subsLSM_.getMinSelectionIndex(), 0));
  }

  public void selectSub(SubRoute sub) {

    int r = 0;
    for(SubRoute s : getSelectedRoute().getSubRoutes()) {
      if (sub == s) break;
      r++;
    }

    subsTable_.getSelectionModel().setSelectionInterval(r, r);
  }

  private void showSubRouteProperties() {
    subPropsFrame_.setSubRoute(getSelectedSubRoute());

    if(subPropsFrame_.isVisible()) subPropsFrame_.toFront(); // TODO: doesn't seem to work..
    else subPropsFrame_.makeVisible(av_.getGUI());
  }

  /////////////////////////////// HELPER CLASS  ////////////////////////////////

  public class RouteListCellRenderer extends DefaultListCellRenderer {

    @Override
    public Component getListCellRendererComponent(JList list,
            Object value,
            int index,
            boolean isSelected,
            boolean cellHasFocus) {

      super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
      if (routeLookup_[index].getScenario() != av_.getActiveScenario()) {
        this.setForeground(Color.GRAY);
      }
      if (routeLookup_[index].getID().indexOf("~") >= 0) {
        this.setForeground(Color.BLUE);
      }

      return this;
    }
  }
}


























